package main

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/wailsapp/wails/v3/pkg/application"
	"log"
	"os"
	"os/exec"
	"syscall"
)

const dataCache = "./data/data.json"

type AppServer struct {
	app              *application.App
	mainWindow       *application.WebviewWindow
	deviceListWindow *application.WebviewWindow
	Data             appData
	ctx              context.Context
}
type appData struct {
	IsTop   bool `json:"is_top"`
	IsAwake bool `json:"is_awake"`
}

func (a *AppServer) init(app *application.App, mainWindow *application.WebviewWindow) {
	a.app = app
	a.mainWindow = mainWindow
	a.ctx = context.Background()
	a.Data = appData{}
	data, err := os.ReadFile(dataCache)
	if err == nil {
		return
	}
	_ = json.Unmarshal(data, &a.Data)
}

func (a *AppServer) onClose() {
	if cmdScrcpy != nil {
		_ = cmdScrcpy.Process.Kill()
	}
}

var cmdScrcpy *exec.Cmd
var isDoing = false

func (a *AppServer) ConnPhoneDef() error {
	deviceName, err := getMyDevice()
	if err != nil {
		return err
	}
	return a.ConnPhoneHelpWithDeviceName(deviceName, a.Data.IsTop, a.Data.IsAwake)
}
func (a *AppServer) ConnPhone(isTop, isAwake bool) error {
	a.Data.IsTop = isTop
	a.Data.IsAwake = isAwake
	if bs, err := json.Marshal(a.Data); err == nil {
		_ = os.WriteFile(dataCache, bs, 0777)
	}
	a.ConnPhoneWithSelect()
	return nil
	//return a.ConnPhoneHelp(a.Data.IsTop, a.Data.IsAwake)
}

func (a *AppServer) ConnPhoneHelpWithDeviceName(deviceName string, isTop, isAwake bool) error {
	if isDoing {
		return errors.New("程序正在运行")
	}
	isDoing = true
	defer func() { isDoing = false }()
	if cmdScrcpy != nil {
		return errors.New("请先退出app")
	}
	args := []string{"-s", deviceName}
	if isTop {
		args = append(args, "--always-on-top")
	}
	if isAwake {
		args = append(args, "--stay-awake")
	}
	//windows.ShellExecute()
	cmdScrcpy = exec.CommandContext(a.ctx, "./scrcpy/scrcpy.exe", args...)
	log.Println(cmdScrcpy.String())
	//cmdScrcpy.SysProcAttr = &syscall.SysProcAttr{
	//	HideWindow:    true,
	//	CreationFlags: 0x08000000,
	//}
	cmdScrcpy.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000}
	//cmdScrcpy = exec.CommandContext(a.ctx, "wscript.exe", "CreateObject(\"Wscript.Shell\").Run strCommand, 0, false ./scrcpy/scrcpy.exe --always-on-top --stay-awake")
	//cmdScrcpy.SysProcAttr = &syscall.SysProcAttr{NoInheritHandles: false}
	log.Println("conn Phone")
	defer func() {
		cmdScrcpy = nil
		log.Println("exit Phone")
	}()
	cmdScrcpy.Stdout = log.New(os.Stdout, "【scrcpy】", log.LstdFlags).Writer()
	if err := cmdScrcpy.Run(); err != nil {
		log.Println(err)
		return err
	}
	return nil
	//scrcpy --always-on-top --stay-awake
}

func (a *AppServer) ConnPhoneHelp(isTop, isAwake bool) error {
	deviceName, err := getMyDevice()
	if err != nil {
		return err
	}
	return a.ConnPhoneHelpWithDeviceName(deviceName, isTop, isAwake)
}

func (a *AppServer) Msg(title, msg string) (string, error) {
	application.InfoDialog().SetTitle(title).SetMessage(msg).Show()
	return "", nil
}

func (a *AppServer) InstallApk() error {
	deviceName, err := getMyDevice()
	if err != nil {
		return err
	}
	p, err := application.OpenFileDialog().
		CanChooseFiles(true).
		AddFilter("apk", "*.apk").
		ShowHiddenFiles(true).
		AttachToWindow(a.mainWindow).SetTitle("选择apk文件").
		PromptForSingleSelection()
	if err != nil {
		log.Println("路径不对", err)
		return err
	}
	installCmd := exec.CommandContext(a.ctx, "./scrcpy/adb.exe", "-s", deviceName, "install", p)
	installCmd.SysProcAttr = &syscall.SysProcAttr{
		HideWindow:    true,
		CreationFlags: 0x08000000,
	}
	installCmd.Stdout = log.New(os.Stdout, "【adb】", log.LstdFlags).Writer()
	if err := installCmd.Run(); err != nil {
		log.Println(err, p)
		return err
	}
	return nil
}

func (a *AppServer) UnInstallApk() error {
	//./adb.exe -s 721QECRS37PSK  shell pm list packages -3
	deviceName, err := getMyDevice()
	if err != nil {
		return err
	}
	bs, err := os.ReadFile(".package")
	if err != nil {
		log.Println(err)
		return err
	}
	installCmd := exec.CommandContext(a.ctx, "./scrcpy/adb.exe", "-s", deviceName, "uninstall", string(bs))
	installCmd.Stdout = log.New(os.Stdout, "【adb】", log.LstdFlags).Writer()
	//installCmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
	//cmd := exec.Command("your_script.exe")
	installCmd.SysProcAttr = &syscall.SysProcAttr{
		HideWindow:    true,
		CreationFlags: 0x08000000,
	}
	if err := installCmd.Run(); err != nil {
		log.Println(err)
		return err
	}
	return nil
}

func (a *AppServer) ConnPhoneWithSelect() {
	ss, _ := getDevices()
	ll := len(ss)
	if ll > 1 {
		a.showList()
	} else if ll == 1 {
		_ = appServer.ConnPhoneDef()
	} else {
		_, _ = appServer.Msg("操作失败", "未发现设备")
	}

}
func (a *AppServer) closeList() {
	if a.deviceListWindow != nil {
		a.deviceListWindow.Close()
		a.deviceListWindow.Destroy()
	}
}
func (a *AppServer) showList() {
	if a.deviceListWindow != nil {
		a.deviceListWindow.Close()
		a.deviceListWindow = nil
	}
	a.deviceListWindow = a.app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
		URL: "list.html",
		//HTML:      buf.String(),
		Width:    0,
		Height:   0, //int(120 * s.Scale),
		Centered: true,
		//Frameless: true,
		DevToolsEnabled:  true,
		DisableResize:    true,
		BackgroundColour: application.RGBA{Red: 27, Green: 38, Blue: 54, Alpha: 1},
		Windows: application.WindowsWindow{
			BackdropType: application.Tabbed,
		},
		//BackgroundColour: application.RGBA{Red: 0xff, Green: 0xff, Blue: 0xff, Alpha: 1},
	})

	a.deviceListWindow.Show()
}
